home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 7: Sunsite / Linux Cubed Series 7 - Sunsite Vol 1.iso / system / network / info-sys / www / tkhtml-2.3 / tkhtml-2 / tkHTML-2.3 / tix / Combobox.tcl next >
Encoding:
Text File  |  1995-02-12  |  16.4 KB  |  653 lines

  1. proc tixCombobox {w args} {
  2.     eval tixInt_CreateWidget $w tixCbx TixCombobox $args
  3.     return $w
  4. }
  5.  
  6. # Obsolete
  7. proc tixComboBox {w args} {
  8.     eval tixInt_CreateWidget $w tixCbx TixCombobox $args
  9.     return $w
  10. }
  11.  
  12. proc tixCbx::CreateClassRec {} {
  13.     global tixCbx
  14.  
  15.     # OPTIONS
  16.     set tixCbx(rootOptions)   {}
  17.     set tixCbx(options)       {-command -fancy
  18.                            -type -state -anchor
  19.                                -scrollbar -histlimit
  20.                    -background -foreground -bg -fg
  21.                    -disabledforeground
  22.                    -entrywidth -entrybg -entryfont
  23.                    -listboxbg -listboxfont -listboxheight
  24.                    -width -height
  25.                    }
  26.  
  27.     # DEFAULT VALUES
  28.     set tixCbx(-anchor)       {-anchor anchor Anchor w}
  29.     set tixCbx(-command)      {-command command Command {}}
  30.     set tixCbx(-state)        {-state state State normal}
  31.     set tixCbx(-type)         {-type type Type static}
  32.     set tixCbx(-histlimit)    {-histlimit histLimit HistLimit 20}
  33.     set tixCbx(-fancy)        {-fancy fancy Fancy "false"}
  34.     set tixCbx(-scrollbar)    {-scrollbar scrollbar Scrollbar y}
  35.  
  36.     # Sub widget default
  37.     set tixCbx(-background)   {-background background Background #ffe4c4}
  38.     set tixCbx(-foreground)   {-foreground foreground Foreground black}
  39.     set tixCbx(-disabledforeground) {\
  40.                            -disabledforeground\
  41.                            -disabledForeground\
  42.                            -DisabledForeground #606060}
  43.     set tixCbx(-entrywidth)   {-entrywidth entryWidth EntryWidth 10}
  44.     set tixCbx(-entryfont)    {-entryfont entryFont Font \
  45.                              "-*-helvetica-medium-r-normal-*-14-*-*-*-*-*-*-*"}
  46.     set tixCbx(-entrybg)      {-entrybg entryBg EntryBg #ffe4c4}
  47.     set tixCbx(-listboxbg)    {-listboxbg listboxBg ListbixBg #ffe4c4}
  48.     set tixCbx(-listboxfont)  {-listboxfont listboxFont Font \
  49.                          "-*-helvetica-medium-r-normal-*-14-*-*-*-*-*-*-*"}
  50.     set tixCbx(-listboxheight) {-listboxheight listboxHeight ListboxHeight 6}
  51.  
  52.     # ALIASES
  53.     set tixCbx(-width)        {= -entrywidth}
  54.     set tixCbx(-height)       {= -listboxheight}
  55.     set tixCbx(-bg)           {= -background}
  56.     set tixCbx(-fg)           {= -foreground}
  57.  
  58.     # METHODS
  59.     set tixCbx(methods)       {listbox entry get pick addhistory appendhistory\
  60.                                align}
  61. }
  62.  
  63. proc tixCbx::ConstructWidget {w} {
  64.     upvar #0 $w data
  65.     global TIX_SOURCE_DIR
  66.  
  67.     # Create the static part of the combo box
  68.     #----------------------------------------
  69.     set data(entry) [entry $w.ent \
  70.              -width $data(-entrywidth) -font $data(-entryfont) \
  71.              -bg $data(-entrybg) -fg $data(-foreground)]
  72.     set data(cross) [button $w.cross -bitmap @$TIX_SOURCE_DIR/bitmaps/cross\
  73.              -bg $data(-background) \
  74.              -fg red]
  75. #             -fg $data(-foreground)]
  76.     set data(tick)  [button $w.tick  -bitmap @$TIX_SOURCE_DIR/bitmaps/tick\
  77.              -bg $data(-background) \
  78.              -fg DarkGreen]
  79. #             -fg $data(-foreground)]
  80.     set data(btn)   [button $w.btn -bitmap @$TIX_SOURCE_DIR/bitmaps/cbxarrow\
  81.              -bg $data(-background) \
  82.              -fg $data(-foreground)]
  83.  
  84.     if {$data(-fancy) == "true" || $data(-fancy) == "yes"} {
  85.     pack $w.cross -side left -padx 1
  86.     pack $w.tick  -side left -padx 1
  87.     }
  88.     pack $w.btn -side right -padx 1
  89.     pack $w.ent -side left -fill x -expand yes -padx 1
  90.  
  91.  
  92.     # Create the shell and the list
  93.     #------------------------------
  94.  
  95.     set data(shell) [toplevel $w.shell -border 2 -relief raised\
  96.              -bg $data(-background) -cursor arrow]
  97.     wm overrideredirect $w.shell 1
  98.     wm withdraw $w.shell
  99.  
  100.     set data(slb) \
  101.     [tixScrolledListbox $w.shell.slb \
  102.      -scrollbar $data(-scrollbar) \
  103.      -anchor $data(-anchor) \
  104.      -listboxbg $data(-listboxbg)\
  105.      -bg $data(-background)\
  106.      -fg $data(-foreground)\
  107.      -font $data(-listboxfont)]
  108.  
  109.     pack $data(slb) -expand yes -fill both
  110.  
  111.     # Set the behavior of the combobox
  112.     #---------------------------------
  113.  
  114.     bind $data(entry) <Down>     "tixCbx::EntArrowKeyDown $w"
  115.     bind $data(entry) <Up>       "tixCbx::EntArrowKeyUp   $w"
  116.     bind $data(entry) <Return>   "tixCbx::EntReturn $w"
  117.     bind $data(entry) <Double-ButtonPress-1> "tixCbx::EntReturn $w"
  118.     bind $data(entry) <1>        "+focus %W"
  119.     bind $data(entry) <1>        "+[bind Entry <1>]"
  120.     global tix_priv
  121.     if [info exists tix_priv(as_loaded)] {
  122.     tixAutoS_BindEntry $data(entry)
  123.     }
  124.  
  125.     bind [$data(slb) listbox] <Down>      "tixCbx::LbArrowKeyDown $w"
  126.     bind [$data(slb) listbox] <Up>        "tixCbx::LbArrowKeyUp   $w"
  127.     bind [$data(slb) listbox] <Return>    "tixCbx::LbReturn $w"
  128.  
  129.     bind [$data(slb) listbox] <B1-Motion> "tixCbx::LbButton $w %y"
  130.     bind [$data(slb) listbox] <1>         "tixCbx::LbButton $w %y"
  131.     bind [$data(slb) listbox] <ButtonRelease-1> "tixCbx::LbRelease $w %x %y"
  132.     if [info exists tix_priv(as_loaded)] {
  133.     tixAutoS_BindListboxSingle [$data(slb) listbox]
  134.     }
  135.  
  136.     # Note that <1> is treated the same as escape if it happens
  137.     # outsides of the combobox
  138.     bind [$data(slb) listbox] <Escape> "tixCbx::EscKey $w"
  139.     bind $data(entry)   <Escape> "tixCbx::EscKey $w"
  140.     bind $data(btn)     <Escape> "tixCbx::EscKey $w"
  141.     bind $w             <Escape> "tixCbx::EscKey $w"
  142.     bind $w             <1>      "tixCbx::EscKey $w"
  143.  
  144.  
  145.     $data(btn)   config -command "tixCbx::BtnUp $w"
  146.     $data(tick)  config -command "tixCbx::EntReturn $w"
  147.     $data(cross) config -command "tixCbx::ClearEntry $w"
  148.  
  149.     if {$data(editable) != "1"} {
  150.     global tixOption
  151.     $data(entry) config -bg $tixOption(bg)
  152.     }
  153. }
  154.  
  155. proc tixCbx::InitWidgetRec {w class className args} {
  156.     upvar #0 $w data
  157.  
  158.     set data(grabbed)      0
  159.     set data(first_expose) 1
  160.     set data(flag)         0
  161.     set data(histCount)    0
  162.  
  163.     if {$data(-type) == "history" || $data(-type) == "editable"} {
  164.     set data(editable) 1
  165.     } else {
  166.     set data(editable) 0
  167.     }
  168. }
  169.  
  170. proc tixCbx::SetBindings {w} {
  171.     upvar #0 $w data
  172.  
  173.     bind $w <Expose> "tixCbx::Expose $w"
  174. }
  175.  
  176. #----------------------------------------------------------------------
  177. #                           CONFIG OPTIONS
  178. #----------------------------------------------------------------------
  179. proc tixCbx::config-anchor {w arg} {
  180.     # $$temp not implemented
  181. }
  182.  
  183. proc tixCbx::config-background {w arg} {
  184.     upvar #0 $w data
  185.  
  186.     $data(cross) config -bg $arg
  187.     $data(tick)  config -bg $arg
  188.     $data(btn)   config -bg $arg
  189.     $data(shell) config -bg $arg
  190.     $data(slb)   config -bg $arg
  191. }
  192.  
  193. proc tixCbx::config-foreground {w arg} {
  194.     upvar #0 $w data
  195.  
  196.     $data(entry) config -fg $arg
  197.     $data(cross) config -fg $arg
  198.     $data(tick)  config -fg $arg
  199.     $data(btn)   config -fg $arg
  200.     $data(slb)   config -fg $arg
  201. }
  202.  
  203. proc tixCbx::config-entrybg {w arg} {
  204.     upvar #0 $w data
  205.  
  206.     $data(entry) config -bg $arg
  207. }
  208.  
  209. proc tixCbx::config-entryfont {w arg} {
  210.     upvar #0 $w data
  211.  
  212.     $data(entry) config -font $arg
  213. }
  214.  
  215. proc tixCbx::config-entrywidth {w arg} {
  216.     upvar #0 $w data
  217.  
  218.     $data(entry) config -width $arg
  219. }
  220.  
  221. proc tixCbx::config-listboxbg {w arg} {
  222.     upvar #0 $w data
  223.  
  224.     $data(slb) config -listboxbg $arg
  225. }
  226.  
  227. proc tixCbx::config-listboxfont {w arg} {
  228.     upvar #0 $w data
  229.  
  230.     $data(slb) config -font $arg
  231. }
  232.  
  233. proc tixCbx::config-state {w arg} {
  234.     upvar #0 $w data
  235.  
  236.     if {$arg == "normal"} {
  237.     $data(entry) config -fg $data(-foreground)
  238.     $data(btn)   config -state normal
  239.     $data(tick)  config -state normal
  240.     $data(cross) config -state normal
  241.     } else {
  242.     $data(entry) config -fg $data(-disabledforeground)
  243.     $data(btn)   config -state disabled
  244.     $data(tick)  config -state disabled
  245.     $data(cross) config -state disabled
  246.     }
  247. }
  248.  
  249. #proc tixCbx::config-type {w arg} {
  250. #    error "Cannot reconfigure -type after widget creation"
  251. #}
  252.  
  253. proc tixCbx::config-listboxheight {w arg} {
  254.     upvar #0 $w data
  255.  
  256.     $data(slb) config -geom $data(-entrywidth)x$data(-listboxheight)
  257. }
  258.  
  259. proc tixCbx::config-entrywidth {w arg} {
  260.     upvar #0 $w data
  261.     $data(entry) config -width $data(-entrywidth)
  262. }
  263.  
  264. #----------------------------------------------------------------------
  265. #                     WIDGET COMMANDS
  266. #----------------------------------------------------------------------
  267. proc tixCbx::listbox {w args} {
  268.     upvar #0 $w data
  269.  
  270.     if {$args != {}} {
  271.     return [eval $data(slb) listbox $args]
  272.     } else {
  273.     return [$data(slb) listbox]
  274.     }
  275. }
  276.  
  277. proc tixCbx::entry {w args} {
  278.     upvar #0 $w data
  279.  
  280.     if {$args == {}} {
  281.     return $data(entry)
  282.     } elseif {[lindex $args 0] == "set"} {
  283.     if {$data(editable) == "0"} {
  284.         $data(entry) config -state normal
  285.     }
  286.     $data(entry) delete 0 end
  287.     $data(entry) insert 0 [lindex $args 1]
  288.     if {$data(editable) == "0"} {
  289.         $data(entry) config -state disabled
  290.     }
  291.     if {$data(-anchor) == "e"} {
  292.         tixCbx::EntryAlignEnd $w
  293.     }
  294.     } else {
  295.     return [eval $data(entry) $args]
  296.     }
  297. }
  298.  
  299. proc tixCbx::pick {w args} {
  300.     upvar #0 $w data
  301.  
  302.     if {$data(editable) == "0"} {
  303.     $data(entry) config -state normal
  304.     }
  305.     if {[llength $args] == "2"} {
  306.     set index [lindex $args 1]
  307.     $data(slb) listbox select from $index
  308.     $data(slb) listbox select to   $index
  309.     set text [$data(slb) listbox get $index]
  310.     } else {
  311.     set text [lindex $args 0]
  312.     }
  313.     $data(entry) delete 0 end
  314.     $data(entry) insert 0 $text
  315.  
  316.     #kludge : if pick before exposing, picked item will be lost
  317.  
  318.     if {$data(first_expose) == "1"} {
  319.     set data(first_expose) 0
  320.     }
  321.     if {$data(editable) == "0"} {
  322.     $data(entry) config -state disabled
  323.     }
  324. }
  325.  
  326. proc tixCbx::addhistory {w newtext} {
  327.     upvar #0 $w data
  328.  
  329.     set indices [$data(slb) listbox curselection]
  330.     if {$indices == "" } {
  331.     set i 0
  332.     } else {
  333.     set i [lindex $indices 0]
  334.     }
  335.     set newtext [string trim $newtext]
  336.     if {$newtext != ""} {
  337.     $data(slb) listbox insert $i $newtext
  338.     $data(slb) listbox select from $i
  339.     $data(slb) listbox select to   $i
  340.     $data(slb) listbox yview $i
  341.     }
  342.     if {$data(histCount) == $data(-histlimit)} {
  343.     $data(slb) listbox delete end
  344.     } else {
  345.     incr data(histCount)
  346.     }
  347. }
  348.  
  349. proc tixCbx::appendhistory {w newtext} {
  350.     upvar #0 $w data
  351.  
  352.     $data(slb) listbox insert end $newtext
  353.     if {$data(histCount) == $data(-histlimit)} {
  354.     $data(slb) listbox delete 0
  355.     } else {
  356.     incr data(histCount)
  357.     }
  358. }
  359.  
  360. proc tixCbx::align {w} {
  361.     upvar #0 $w data
  362.  
  363.     if {$data(-anchor) == "e"} {
  364.     tixCbx::EntryAlignEnd $w
  365.     }
  366. }
  367.  
  368. proc tixCbx::get {w} {
  369.     upvar #0 $w data
  370.  
  371.     return [$data(entry) get]
  372. }
  373.  
  374. #----------------------------------------------------------------------
  375. #                   E V E N T   B I N D I N G S
  376. #----------------------------------------------------------------------
  377. proc tixCbx::BtnUp {w} {
  378.     upvar #0 $w data
  379.  
  380.     if {$data(grabbed) == 0} {
  381.     tixCbx::PopupShell $w
  382.     } else {
  383.     tixCbx::RestoreValue $w
  384.     tixCbx::PopdownShell $w
  385.     }
  386. }
  387.  
  388. proc tixCbx::EntArrowKeyUp {w} {
  389.     upvar #0 $w data
  390.  
  391.     if {$data(grabbed) == 0} {
  392.     tixCbx::PopupShell $w
  393.     tixCbx::SetEntry $w
  394.     } else {
  395.     tixCbx::LbArrowKeyUp $w
  396.     }
  397. }
  398.  
  399. proc tixCbx::EntArrowKeyDown {w} {
  400.     upvar #0 $w data
  401.  
  402.     if {$data(grabbed) == 0} {
  403.     tixCbx::PopupShell $w
  404.     tixCbx::SetEntry $w
  405.     } else {
  406.     tixCbx::LbArrowKeyDown $w
  407.     }
  408. }
  409.  
  410. proc tixCbx::EntReturn {w} {
  411.     upvar #0 $w data
  412.  
  413.     if {$data(grabbed) != 0} {
  414.     tixCbx::PopdownShell $w
  415.     }
  416.  
  417.     set old_bg [lindex [$data(entry) config -bg] 4]
  418.     set old_fg [lindex [$data(entry) config -fg] 4]
  419.     $data(entry) config -fg $old_bg
  420.     $data(entry) config -bg $old_fg
  421.     update idletasks
  422.     $data(entry) config -fg $old_fg
  423.     $data(entry) config -bg $old_bg
  424.  
  425.     if {$data(-command) != {} && $data(-command) != "" } {
  426.     eval $data(-command) [list [$data(entry) get]]
  427.     }
  428.  
  429.     if {$data(-type) == "history"} {
  430.     tixCbx::addhistory $w [$data(entry) get]
  431.     }
  432. }
  433.  
  434. proc tixCbx::LbButton {w y} {
  435.     upvar #0 $w data
  436.     $data(slb) listbox select clear
  437.     $data(slb) listbox select from [$data(slb) listbox nearest $y]
  438.     tixCbx::SetEntry $w
  439. }
  440.  
  441. proc tixCbx::LbReturn {w} {
  442.     upvar #0 $w data
  443.  
  444.     tixCbx::PopdownShell $w
  445.     if {$data(-command) != {} && $data(-command) != "" } {
  446.     eval $data(-command) [list [$data(entry) get]]
  447.     }
  448. }
  449.  
  450. proc tixCbx::LbRelease {w x y} {
  451.     upvar #0 $w data
  452.  
  453.     if {$x < 0 || $y < 0} {
  454.     return
  455.     }
  456.     set listbox [$data(slb) listbox]
  457.     if {$x > [winfo width $listbox]} {
  458.     return
  459.     }
  460.     if {$y > [winfo height $listbox]} {
  461.     return
  462.     }
  463.  
  464.     tixCbx::PopdownShell $w
  465.     if {$data(-command) != {} && $data(-command) != "" } {
  466.     eval $data(-command) [list [$data(entry) get]]
  467.     }
  468. }
  469.  
  470.  
  471. proc tixCbx::LbArrowKeyUp {w} {
  472.     upvar #0 $w data
  473.  
  474.     set indices [$data(slb) listbox curselection]
  475.     if {$indices == "" } {
  476.     $data(slb) listbox select from 0
  477.     $data(slb) listbox select to   0
  478.     $data(slb) listbox yview 0
  479.     } else {
  480.     set i [lindex $indices 0]
  481.     if {$i > 0} {
  482.         incr i -1
  483.         $data(slb) listbox select from $i
  484.         $data(slb) listbox select to   $i
  485.         set height [$data(slb) info height]
  486.         set yview  [$data(slb) info yview]
  487.         if {$i < $yview || $i >= [expr "$yview+$height"]} {
  488.         $data(slb) listbox yview $i
  489.         }
  490.     }
  491.     }
  492.     tixCbx::SetEntry $w
  493. }
  494.  
  495.  
  496. proc tixCbx::LbArrowKeyDown {w} {
  497.     upvar #0 $w data
  498.  
  499.     set indices [$data(slb) listbox curselection]
  500.     if {$indices == "" } {
  501.     $data(slb) listbox select from 0
  502.     $data(slb) listbox select to   0
  503.     $data(slb) listbox yview 0
  504.     } else {
  505.     set i [lindex $indices 0]
  506.     incr i
  507.     if {$i < [$data(slb) info totalheight]} {
  508.         $data(slb) listbox select from $i
  509.         $data(slb) listbox select to   $i
  510.         set height [$data(slb) info height]
  511.         set yview  [$data(slb) info yview]
  512.         if {$i < $yview || $i >= [expr "$yview+$height"]} {
  513.         $data(slb) listbox yview [expr "$i - $height + 1"]
  514.         }
  515.     }
  516.     }
  517.     tixCbx::SetEntry $w
  518. }
  519.  
  520. proc tixCbx::EscKey {w} {
  521.     upvar #0 $w data
  522.     
  523.     if {$data(grabbed) == "1"} {
  524.     tixCbx::RestoreValue $w
  525.     tixCbx::PopdownShell $w
  526.     }
  527. }
  528.  
  529. proc tixCbx::Expose {w} {
  530.     upvar #0 $w data
  531.  
  532.     if {$data(first_expose) == "1"} {
  533.     set data(first_expose) 0
  534.     tixCbx::SetEntry $w
  535.     }
  536. }
  537.  
  538. #----------------------------------------------------------------------
  539. # Internal commands
  540. #----------------------------------------------------------------------
  541. proc tixCbx::SetEntry {w} {
  542.     upvar #0 $w data
  543.  
  544.     set indices [$data(slb) listbox curselection]
  545.     if {$indices != ""} {
  546.     set i [lindex $indices 0]
  547.     } else {
  548.     set i 0
  549.     }
  550.     if {$data(editable) == "0"} {
  551.     $data(entry) config -state normal
  552.     }
  553.     $data(entry) delete 0 end
  554.     $data(entry) insert 0 [$data(slb) listbox get $i]
  555.     if {$data(editable) == "0"} {
  556.     $data(entry) config -state disabled
  557.     }
  558.     focus $data(entry)
  559. }
  560.  
  561. proc tixCbx::ClearEntry {w} {
  562.     upvar #0 $w data
  563.  
  564.     $data(entry) delete 0 end
  565. }
  566.  
  567. proc tixCbx::PopdownShell {w} {
  568.     upvar #0 $w data
  569.  
  570.     wm withdraw $data(shell)
  571.     focus $data(entry)
  572.     $data(rootCmd) config -cursor {}
  573.     grab release $data(root)
  574.     set data(grabbed) 0
  575. }
  576.  
  577. proc tixCbx::RestoreValue {w} {
  578.     upvar #0 $w data
  579.  
  580.     if {$data(editable) == "0"} {
  581.     $data(entry) config -state normal
  582.     }
  583.     $data(entry) delete 0 end
  584.     $data(entry) insert 0 $data(oldvalue)
  585.     if {$data(editable) == "0"} {
  586.     $data(entry) config -state disabled
  587.     }
  588. }
  589.  
  590. # Calculating the geometry of the combo box
  591. #
  592. # +4 in the height because of the frames surrounding the listbox
  593. proc tixCbx::PopupShell {w} {
  594.     upvar #0 $w data
  595.  
  596.     # pop up the shell
  597.     set y [expr [winfo rooty $data(entry)]+[winfo height $data(entry)]+3]
  598.     $data(slb) config -geom $data(-entrywidth)x$data(-listboxheight)
  599.     set height [expr "[winfo reqheight [$data(slb) listbox]]+4"]
  600.  
  601.     set x1 [winfo rootx $data(entry)]
  602.     set x2 [expr "[winfo rootx $data(btn)] + [winfo width $data(btn)]"]
  603.     set width  [expr "$x2 - $x1"]
  604.  
  605.     # If the listbox is below bottom of screen, put it upwards
  606.     set scrheight [winfo screenheight .]
  607.     set bottom [expr $y+$height]
  608.     if {$bottom > $scrheight} {
  609.     set y [expr $y-$height-[winfo height $data(entry)]-5]
  610.     }
  611.  
  612.     wm geometry $data(shell) $width\x$height+$x1+$y
  613.     wm deiconify $data(shell)
  614.     raise $data(shell)
  615.     focus $data(entry)
  616.  
  617.     if {[$data(slb) listbox curselection] == ""} {
  618.     $data(slb) listbox select from 0
  619.     $data(slb) listbox select to   0
  620.     }
  621.     $data(rootCmd) config -cursor arrow
  622.  
  623.     set data(grabbed) 1
  624.     set data(oldvalue) [$data(entry) get]
  625.     catch {
  626.     grab -global $data(root)
  627.     }
  628. }
  629.  
  630. # The following two routines can emulate a "right align mode" for the
  631. # entry in the combo box.
  632. proc tixCbx::MonitorEntry {w total max begin end} {
  633.     upvar #0 $w data
  634.  
  635.     if {$data(flag) == 0} {
  636.     set data(flag) 1
  637.     if {$total > $max && $total > [expr $end +1]} {
  638.         $data(entry) view [expr "$total - $max + 1"]
  639.     }
  640.     set data(flag) 0
  641.     }
  642. }
  643.  
  644. proc tixCbx::EntryAlignEnd {w} {
  645.     upvar #0 $w data
  646.  
  647.     set data(flag) 0
  648.     $data(entry) config \
  649.     -scroll "tixCbx::MonitorEntry $w"
  650.     update idletasks
  651.     $data(entry) config -scroll {}
  652. }
  653.